#include "include/global.h"
#include "include/type.h"
#include "include/klib.h"
#include "include/kconst.h"
#include "include/proc.h"
#include "include/irq.h"
#include "include/clock.h"
#include "include/syscall.h"
#include "include/keyboard.h"
#include "include/printf.h"
#include "include/misc.h"
void restart();

int kernel_main()
{
    
    PROCESS* p_proc = proc_table;
	TASK*	p_task;
	char* p_task_stack = 0x4000*PROC_SZ;
	u16 selector_ldt = SELECTOR_LDT_FIRST;

	u8 privilege;
	u8 rpl;
	int eflags;

	ticks = 0;
	cls();
	for (int i = 0; i < PROC_SZ; i++)
	{
		if (i < NR_TASKS)
		{
			p_task = task_table + i;
			privilege = PRIVILEGE_TASK;
			rpl = RPL_TASK;
			eflags = 0x1202;
		}
		else 
		{
			p_task = user_proc_table + (i - NR_TASKS);
			privilege = PRIVILEGE_USER;
			rpl = RPL_USER;
			eflags = 0x202;
		}
		strcpy(p_task->name, p_proc->p_name);
		p_proc->pid = i;
		p_proc->ldt_sel = selector_ldt;
		p_proc->nr_tty = 0;

		p_proc->p_flags = 0;
		p_proc->has_int_msg = 0;
		p_proc->next_sending = 0;
		p_proc->p_recvfrom = NO_TASK;
		p_proc->p_sendto = NO_TASK;
		p_proc->p_msg = 0;
		p_proc->q_sending = 0;

		memcpy(&p_proc->ldts[0], &gdt[INDEX_FLAT_C],sizeof(DESCRIPTOR));
		p_proc->ldts[0].attr1 = DA_C | privilege << 5;
		memcpy(&p_proc->ldts[1], &gdt[INDEX_FLAT_RW], sizeof(DESCRIPTOR));
		p_proc->ldts[1].attr1 = DA_DRW | privilege << 5;

		p_proc->regs.cs	= (0 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl;
		p_proc->regs.ds	= (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl;
		p_proc->regs.es	= (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl;
		p_proc->regs.fs	= (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl;
		p_proc->regs.ss	= (8 & SA_RPL_MASK & SA_TI_MASK) | SA_TIL | rpl;
		p_proc->regs.gs	= (SELECTOR_VIDEO & SA_RPL_MASK) | RPL_TASK;

		p_proc->regs.eip = (u32) p_task->initial_eip;
		p_proc->regs.esp = (u32) p_task_stack;
		p_proc->regs.eflags = eflags; // IF=1, IOPL=1, bit 2 is always 1.
		
		p_task_stack -= p_task->stacksize;

		p_proc++;
		p_task++;
		selector_ldt += 1 << 3;

	}
	//设置进程所属的TTY
	proc_table[2].nr_tty = 1;
	proc_table[3].nr_tty = 2;

	k_reenter = 0;
	p_proc_ready	= proc_table;

	init_clock();

	
	//panic();
    restart();

}

void TestA()
{
	int i = 0;
	MESSAGE msg;
	msg.type = 1001;
	send_recv(SEND, TASK_HD, &msg);
	while(1){
		disp_str("A",0x000f0000);
		disp_u32(i++,0x000f0001);
		milli_delay(1000);
	}
}
void TestB()
{
	int i = 0;
	
	while(1){
		disp_str("B",0x000f0100);
		disp_u32(i++,0x000f0101);
		milli_delay(1000);
	}
}
void TestC()
{
	int i = 16;
	while(1) {
		disp_str("C",0x000f0200);
		disp_u32(i++,0x000f0201);
		milli_delay(1000);
	}
}